/* components */
import TaskAllotModal from '@src/modules/task/components/TaskAllotModal/TaskAllotModal.tsx'
import TaskMapInfoWindow from '@src/modules/task/components/TaskAllotModal/TaskMapInfoWindow/TaskMapInfoWindow.tsx'
/* entity */
import TaskAddress from '@model/entity/TaskAddress'
import Field from '@model/entity/Field'
/* enum */
import ComponentNameEnum from '@model/enum/ComponentNameEnum'
import EventNameEnum from '@model/enum/EventNameEnum'
import TaskStateEnum from '@model/enum/TaskStateEnum'
import { TaskFieldNameMappingEnum } from '@model/enum/FieldMappingEnum'
import { MapTypeEnum } from '@model/enum/MapEnum'
/* util */
import { findComponentUpward } from '@src/util/assist'
import Log from '@src/util/log.ts'
import i18n from '@src/locales'
/* scss */
import '@src/modules/task/components/TaskAllotModal/TaskAllotMap/TaskAllotMap.scss'
import '@src/modules/task/components/TaskAllotModal/TaskMapInfoWindow/TaskMapInfoWindow.scss'
/* vue */
import { Component, Prop, Ref, Inject } from 'vue-property-decorator'
import { CreateElement } from 'vue'
import { useNewVue } from '@hooks/useNewVue'
const { extendVue } = useNewVue();
import VC from '@model/VC'
/* types */
import TaskConfig from '@model/config/TaskConfig'
import TaskType from "@model/entity/TaskType";
import { useMapType } from '@src/util/map'

declare let AMap: any

import { overlayFun, googleOverlayFun } from '@src/util/bMap';
let SquareOverlay:any
// declare let AMap: any
declare let BMap: any
declare let google: any



@Component({ 
  name: ComponentNameEnum.TaskAllotMap,
  components: {
    TaskMapInfoWindow
  }
})
export default class TaskAllotMap extends VC {
  
  /* 工单地图信息弹窗组件 */
  @Ref() readonly TaskMapInfoWindowComponent!: TaskMapInfoWindow
  
  // 地图 id
  @Prop() readonly idName: string | undefined
  // 工单类型列表
  @Prop() readonly taskTypesMap: { [x: string]: TaskType} | undefined
  // 自定义事件
  @Prop() readonly handlerCustomFunc: Function | undefined
  // 设置地图事件
  @Prop() readonly setMapFunc: Function | undefined

  // @Inject({
  //   from:'currentMapType',
  //   default:null
  // })
  public currentMapType:MapTypeEnum|null = null

  
  /* 地图对象 */
  private AMap: any = null
  /* 地图弹窗对象 */
  private AMapInfoWindow: any = null
  /* 是否显示地图弹窗信息 */
  private showMapInfoWindow: boolean = false

  private customerInfoWindow: any = null
  
  /* 是否为创建人 */
  private get isCreator(): boolean {
    return this.TaskAllotModalComponent.outsideIsCreator
  }
  
  /* 是否为负责人 */
  private get isExecutor(): boolean {
    return this.TaskAllotModalComponent.outsideIsExecutor
  }
  
  /* 计划时间字段 */
  private get planTimeField(): Field {
    return this.taskFields.filter(field => field.fieldName === TaskFieldNameMappingEnum.PlanTime)[0] || {}
  }

  /* 计划开始时间字段 */
  private get planStartTimeField(): Field {
    return this.taskFields.filter(field => field.fieldName === TaskFieldNameMappingEnum.PlanStartTime)[0] || {}
  }

  /* 计划完成时间字段 */
  private get planEndTimeField(): Field {
    return this.taskFields.filter(field => field.fieldName === TaskFieldNameMappingEnum.PlanEndTime)[0] || {}
  }
  
  /* 工单派单组件 */
  private get TaskAllotModalComponent(): TaskAllotModal {
    return findComponentUpward(this, ComponentNameEnum.TaskAllotModal) || {}
  }
  
  /* 工单 */
  private get task(): any {
    // 默认是获取的工单派单组件的，如需自定义 需要自己写
    return this.TaskAllotModalComponent.outsideTask || {}
  }
  
  /* 工单 */
  private get taskType(): TaskType {
    return this.taskTypesMap?.[this.task?.templateId] || { id: '', templateId: '' }
  }
  
  /* 工单配置信息 */
  private get taskConfig(): TaskConfig {
    return this.TaskAllotModalComponent.outsideTaskConfig || {}
  }
  
  /* 工单字段列表 */
  private get taskFields(): Field[] {
    return this.TaskAllotModalComponent.outsideFields
  }
  
  /**
   * @description 工单客户地址地址 
   * 工单新建后地址信息在taddress里面，新建的信息在address里面
  */
  get taskAddress(): TaskAddress {
    return new TaskAddress(this.task.taddress || this.task.address || {})
  }
  
  /** 
   * @description 工单信息中计划时间是否可以修改
   * 1. 工单状态是待指派或已拒绝
   * 3. 工单设置允许修改计划时间
  */
  get allowModifyPlanTime() {
    let states = [TaskStateEnum.CREATED.value, TaskStateEnum.REFUSED.value]
    let { state } = this.task
    return this.taskConfig.taskPlanTime && states.indexOf(state) >= 0
  }
  
  /** 
   * @description 构建客户地址标记
  */
  private buildCusomterAddressMarker(): void {
    let { validAddress } = this.taskAddress
    if (!validAddress) {
      return Log.warn('taskAddress.validAddress is false', this.buildCusomterAddressMarker.name)
    }
    const _this = this;
    this.$nextTick(()=>{
      this.$refs.baseMapContainer.setListMark([{
        size:{
          x:32, y:32
        },
        ...this.getMapCenter(),
        markInfo:this.buildCustomerAddressMapMarkerContent(),
        infoWindowFnc:()=>{
          return this.$refs.taskAllotDialogInfowindow
        },
        showInfoWindowType:'mouseover',
        markKey:'cusomter',
        markListKey:'customerAddress'
      }], true, false)
    })
    
    
  }

  /**
   * @description 构建客户地址标记内容
  */
  private buildCustomerAddressMapMarkerContent(): string {
    return `<div class="customer-marker customer-marker-animation"><i class="bm-location-dot"></i><div class="map-address-title">${i18n.t('common.form.type.customerAddress')}</div></div>`;
  }
  
  /**
   * @description 关闭地图标记弹窗
   */
  private closeInfoWindowHandler() {
    this.AMapInfoWindow?.close()
  }
  
  /**
   * @description 获取地图中心
  */
  private getMapCenter():any {
    let { taskAddress } = this
    let { latitude, longitude } = taskAddress
    let center:number[] = []
    
    // 是否为有效地址
    if (taskAddress.validAddress) {
      center = [Number(longitude), Number(latitude)]
    } else {
      // 高德地图不支持国外地址解析，那就手动设置为大首都北京吧
      center = [116.397428, 39.90923]
      console.warn('getMapCenter()=>taskAddress is not validAddress')
    }
    return {lat:center[1] || 39.90923, lng:center[0] ||  116.397428}
  }
  
  /**
   * @description 地图初始化事件
  */
  private mapInit() {
    if (!this.idName) {
      return Log.error('TaskAllotMap component props idName is empty', this.mapInit.name)
    }
    
    Log.succ(Log.Start, this.mapInit.name)
    const latLng = this.getMapCenter();
    setTimeout(()=>{
      this.$refs.baseMapContainer.setMapCenter(null, latLng)
    }, 500)
    
    this.AMap = this.$refs.baseMapContainer;
    
    // 设置地图数据
    this.setMapFunc && this.setMapFunc(this.AMap)
    
    // 自定义操作
    this.handlerCustomFunc && this.handlerCustomFunc()
    // Log
    Log.succ(Log.End, this.mapInit.name)
    
    
    
    
  } 
  
  /**
   * @description 地图初始化事件
   * -- 支持外部调用的
  */
  public outsideMapInit() {
    this.mapInit()
  }
  
  /**
   * @description 计划时间修改变化事件
   * -- 支持外部调用的
  */
  private planTimeChangedHandler(planTime: string) {
    Log.succ(Log.Start, `TaskAllotMap -> ${this.planTimeChangedHandler.name}`)
    this.TaskAllotModalComponent.outsideSetTask({
      ...this.task,
      planTime
    })
  }

  public setInfoWindowDom(){
    const _this = this;
    return (
      <div class="need-hide-in-oversize">
        <div class="task-allot-dialog-infowindow task-map-info-window" ref="taskAllotDialogInfowindow">
          { _this.task && <task-map-info-window
                style="boder:none;margin-bottom:0;"
                onPlanTimeChange={(planTime: string) => _this.planTimeChangedHandler(planTime)}
                ref='TaskMapInfoWindowComponent'
                planTimeField={_this.planTimeField}
                show={true}
                showModifyPlanTime={_this.allowModifyPlanTime}
                task={_this.task}
                taskType={_this.taskType}
                onClose={() => _this.closeInfoWindowHandler()}
              />}
          </div>
      </div>
    )
  }
  async mounted() {
      const { currentMapType } = await useMapType()
      this.currentMapType = currentMapType()
      this.$nextTick(()=>{
        this.mapInit()
        // 构建客户地址标记
        this.buildCusomterAddressMarker()
      })
      
    
  }
  
  render(h: CreateElement) {
    return (
      <div class={[ComponentNameEnum.TaskAllotMap, 'task-allot-map-con']}>
        {this.currentMapType && <bbx-power-map ref="baseMapContainer" currentMapType={this.currentMapType} mapSetting={{zoom:12}} />}
        {this.setInfoWindowDom()}
      </div>
    )
  }
  
}

